package server

import (
	"context"
	"log"
	"os"
	"os/signal"
	"sync"
	"syscall"
)

type ManageServer struct {
	ServerList     []*MyServer
	StopServerChan chan struct{}
	one            *sync.Once
	wg             *sync.WaitGroup
}

func NewManageServer() ManageServer {
	return ManageServer{
		ServerList:     make([]*MyServer, 0),
		StopServerChan: make(chan struct{}),
		one:            &sync.Once{},
		wg:             &sync.WaitGroup{},
	}
}

func (m *ManageServer) RegisterServer(server ...*MyServer) {
	m.ServerList = append(m.ServerList, server...)
}

func (m *ManageServer) StartServer() {
	for i := range m.ServerList {
		m.wg.Add(1)
		go func(i int) {
			//s := m.ServerList[i]
			go func(i int) {
				<-m.StopServerChan
				log.Printf("server:%s stop\n", m.ServerList[i].Name)
				err := m.ServerList[i].Server.Shutdown(context.Background())
				if err != nil {
					log.Printf("stop server err:%v\n", err)
				}
			}(i)
			log.Printf("server:%s start\n", m.ServerList[i].Name)
			err := m.ServerList[i].Server.ListenAndServe()
			if err != nil {
				log.Printf("server:%s err:%v", m.ServerList[i].Name, err)
			}
			m.wg.Done()
		}(i)
	}
	// 检测停止信号
	//g.Go(func() error {
	go func() {
		m.wg.Add(1)
		ch := make(chan os.Signal)
		signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
		select {
		case <-m.StopServerChan:
			m.wg.Done()
			return
		case s := <-ch:
			log.Printf("stop signal:%v\n", s)
		}
		m.StopServer()
		m.wg.Done()
		return
	}()
	m.wg.Wait()
	log.Println("stop all server")
}

func (m *ManageServer) StopServer() {
	m.one.Do(func() {
		close(m.StopServerChan)
	})
}
